{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "713d9b4a",
   "metadata": {},
   "source": [
    "# Usage\n",
    "\n",
    "`decoupler` contains different statistical methods to extract biological activities from omics data using prior knowledge. In this notebook we showcase how to use it with some toy data."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4fc236eb",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-info\">\n",
    "\n",
    "**Note**\n",
    "    \n",
    "In Jupyter notebooks and lab, you can see the documentation for a python function by hitting `SHIFT + TAB`, hit it twice to expand the view, or by typing `?name_of_function`.\n",
    "\n",
    "</div>  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2337c9d3",
   "metadata": {},
   "source": [
    "## Loading packages\n",
    "\n",
    "`decoupler` can be imported as:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "c6c36a9e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import decoupler as dc\n",
    "\n",
    "# Only needed for visualization:\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f069cafc",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-info\">\n",
    "\n",
    "**Note**\n",
    "    \n",
    "The first time `decoupler` is imported in an enviroment can be slow. This is due to numba compiling its source code. After the first usage it will be stored in cache, making the import time normal again.\n",
    "\n",
    "</div>  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3316c8ad",
   "metadata": {},
   "source": [
    "## Loading toy data\n",
    "\n",
    "`decoupler` needs a matrix (`mat`) of molecular readouts (gene expression, logFC, p-values, etc.) and a network (`net`) that relates target features (genes, proteins, etc.) to \"source\" biological entities (pathways, transcription factors, molecular processes, etc.)\n",
    "\n",
    "To load the example data-set, simply run:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "1a85cb79",
   "metadata": {},
   "outputs": [],
   "source": [
    "mat, net = dc.get_toy_data()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "59856674",
   "metadata": {},
   "source": [
    "This example consists of two small populations of samples (S, rows) with different gene expression patterns (G, columns):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "0996787b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.heatmap(mat, cmap='viridis')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6898f90c",
   "metadata": {},
   "source": [
    "Here we can see that some genes seem to be more expressed in one group of samples than in the other and vice-versa. Ideally, we would like to capture these differences in gene programs into interpretable biological entities. In this example we will do it by summarizing gene expression into transcription factor activities."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ab820efd",
   "metadata": {},
   "source": [
    "The toy data also contains a simple `net` consisting of 5 transcription factors (Ts) with specific regulation to target genes (Gs), either positive or negative:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "184c02ee",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>source</th>\n",
       "      <th>target</th>\n",
       "      <th>weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>T1</td>\n",
       "      <td>G01</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>T1</td>\n",
       "      <td>G02</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>T1</td>\n",
       "      <td>G03</td>\n",
       "      <td>0.7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>T2</td>\n",
       "      <td>G04</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>T2</td>\n",
       "      <td>G06</td>\n",
       "      <td>-0.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>T2</td>\n",
       "      <td>G07</td>\n",
       "      <td>-3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>T2</td>\n",
       "      <td>G08</td>\n",
       "      <td>-1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>T3</td>\n",
       "      <td>G06</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>T3</td>\n",
       "      <td>G07</td>\n",
       "      <td>0.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>T3</td>\n",
       "      <td>G08</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>T4</td>\n",
       "      <td>G05</td>\n",
       "      <td>1.9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>T4</td>\n",
       "      <td>G10</td>\n",
       "      <td>-1.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>T4</td>\n",
       "      <td>G11</td>\n",
       "      <td>-2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>T4</td>\n",
       "      <td>G09</td>\n",
       "      <td>3.1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>T5</td>\n",
       "      <td>G09</td>\n",
       "      <td>0.7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>T5</td>\n",
       "      <td>G10</td>\n",
       "      <td>1.1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>T5</td>\n",
       "      <td>G11</td>\n",
       "      <td>0.1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   source target  weight\n",
       "0      T1    G01     1.0\n",
       "1      T1    G02     1.0\n",
       "2      T1    G03     0.7\n",
       "3      T2    G04     1.0\n",
       "4      T2    G06    -0.5\n",
       "5      T2    G07    -3.0\n",
       "6      T2    G08    -1.0\n",
       "7      T3    G06     1.0\n",
       "8      T3    G07     0.5\n",
       "9      T3    G08     1.0\n",
       "10     T4    G05     1.9\n",
       "11     T4    G10    -1.5\n",
       "12     T4    G11    -2.0\n",
       "13     T4    G09     3.1\n",
       "14     T5    G09     0.7\n",
       "15     T5    G10     1.1\n",
       "16     T5    G11     0.1"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "net"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f5a37e7",
   "metadata": {},
   "source": [
    "This network can be visualized like a graph. Green edges are positive regulation (activation), red edges are negative regulation (inactivation):\n",
    "\n",
    "![](../net_plot.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e2eba9a7",
   "metadata": {},
   "source": [
    "According to this network, the first population of samples should show high activity for T1 and T2, while the second one for T3 and T4. T5 should have no activity in all samples."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0adc4371",
   "metadata": {},
   "source": [
    "## Methods\n",
    "\n",
    "`decoupler` contains several methods. To check how many are available, run:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "8d022899",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Function</th>\n",
       "      <th>Name</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>run_aucell</td>\n",
       "      <td>AUCell.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>run_consensus</td>\n",
       "      <td>Consensus score from top methods.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>run_gsea</td>\n",
       "      <td>Gene Set Enrichment Analysis (GSEA).</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>run_gsva</td>\n",
       "      <td>Gene Set Variation Analysis (GSVA).</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>run_mdt</td>\n",
       "      <td>Multivariate Decision Tree (MDT).</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>run_mlm</td>\n",
       "      <td>Multivariate Linear Model (MLM).</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>run_ora</td>\n",
       "      <td>Over Representation Analysis (ORA).</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>run_udt</td>\n",
       "      <td>Univariate Decision Tree (UDT).</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>run_ulm</td>\n",
       "      <td>Univariate Linear Model (ULM).</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>run_viper</td>\n",
       "      <td>Virtual Inference of Protein-activity by Enric...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>run_wmean</td>\n",
       "      <td>Weighted sum (WMEAN).</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>run_wsum</td>\n",
       "      <td>Weighted sum (WSUM).</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         Function                                               Name\n",
       "0      run_aucell                                            AUCell.\n",
       "1   run_consensus                  Consensus score from top methods.\n",
       "2        run_gsea               Gene Set Enrichment Analysis (GSEA).\n",
       "3        run_gsva                Gene Set Variation Analysis (GSVA).\n",
       "4         run_mdt                  Multivariate Decision Tree (MDT).\n",
       "5         run_mlm                   Multivariate Linear Model (MLM).\n",
       "6         run_ora                Over Representation Analysis (ORA).\n",
       "7         run_udt                    Univariate Decision Tree (UDT).\n",
       "8         run_ulm                     Univariate Linear Model (ULM).\n",
       "9       run_viper  Virtual Inference of Protein-activity by Enric...\n",
       "10      run_wmean                              Weighted sum (WMEAN).\n",
       "11       run_wsum                               Weighted sum (WSUM)."
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dc.show_methods()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f64f1bdc",
   "metadata": {},
   "source": [
    "Each method models biological activities in a different manner, sometimes returning more than one estimate or providing significance of the estimation. To know what each method returns, please check their documentation like this `?run_mlm`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "590e371b",
   "metadata": {},
   "source": [
    "To have a unified framework, methods inside `decoupler` have these shared arguments:\n",
    "\n",
    "* `mat` : input matrix of molecular readouts.\n",
    "* `net` : input prior knowledge information relating molecular features to biological entities.\n",
    "* `source`,`target` and `weight` : column names where to extract the information from `net`. \n",
    "    * `source` refers to the biological entities.\n",
    "    * `target` refers to the molecular features.\n",
    "    * `weight` refers to the \"strength\" of the interaction (if available, else 1s will be used). Only available for methods that can model interaction weights.\n",
    "* `min_n` : Minimum of target features per biological entity (5 by default). If less, sources are removed. This filtering prevents obtaining noisy activities from biological entities with very few matching target features in `mat`. For this example data-set we will have to keep it to 0 though.\n",
    "* `verbose` : Whether to show progress.\n",
    "* `use_raw` : When the input is an `AnnData` object, whether to use the data stored in it's `.raw` atribute or not (`True` by default)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0f85f343",
   "metadata": {},
   "source": [
    "## Running methods\n",
    "\n",
    "### Individual methods\n",
    "\n",
    "As an example, let's first run the Gene Set Enrichment Analysis method (`gsea`), one of the most well-known statistics:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "75ccd460",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>source</th>\n",
       "      <th>T1</th>\n",
       "      <th>T2</th>\n",
       "      <th>T3</th>\n",
       "      <th>T4</th>\n",
       "      <th>T5</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>S01</th>\n",
       "      <td>0.888889</td>\n",
       "      <td>0.711597</td>\n",
       "      <td>-0.555556</td>\n",
       "      <td>-0.50</td>\n",
       "      <td>-0.666667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>S02</th>\n",
       "      <td>0.888889</td>\n",
       "      <td>0.699385</td>\n",
       "      <td>-0.555556</td>\n",
       "      <td>-0.50</td>\n",
       "      <td>-0.444444</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>S03</th>\n",
       "      <td>0.888889</td>\n",
       "      <td>0.551198</td>\n",
       "      <td>-0.444444</td>\n",
       "      <td>-0.75</td>\n",
       "      <td>-0.666667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>S04</th>\n",
       "      <td>0.888889</td>\n",
       "      <td>0.607223</td>\n",
       "      <td>-0.666667</td>\n",
       "      <td>-0.50</td>\n",
       "      <td>-0.444444</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>S05</th>\n",
       "      <td>0.888889</td>\n",
       "      <td>0.732963</td>\n",
       "      <td>-0.888889</td>\n",
       "      <td>-0.50</td>\n",
       "      <td>-0.444444</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "source        T1        T2        T3    T4        T5\n",
       "S01     0.888889  0.711597 -0.555556 -0.50 -0.666667\n",
       "S02     0.888889  0.699385 -0.555556 -0.50 -0.444444\n",
       "S03     0.888889  0.551198 -0.444444 -0.75 -0.666667\n",
       "S04     0.888889  0.607223 -0.666667 -0.50 -0.444444\n",
       "S05     0.888889  0.732963 -0.888889 -0.50 -0.444444"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# For this toy data, we need to set min_n to 0 (otherwise it is better to keep at 5):\n",
    "acts, norm_acts, pvals = dc.run_gsea(mat, net, min_n=0, times=100)\n",
    "acts.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ffc2fd1f",
   "metadata": {},
   "source": [
    "In the case of `gsea`, it returns a simple estimate of activities (`acts`), a normalised estimate (`norm_acts`) and `pvals` data-frames after doing permutations."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "44598ded",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-info\">\n",
    "\n",
    "**Note**\n",
    "    \n",
    "If `mat` is an `AnnData` instance, results will instead be saved in its `.obsm` attribute.\n",
    "\n",
    "</div>  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4f11b1d4",
   "metadata": {},
   "source": [
    "Let us plot the obtained results:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "dd2b1fb4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 648x216 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axes = plt.subplots(1,3, figsize=(9,3), tight_layout=True, sharey=True)\n",
    "\n",
    "axes[0].set_title('acts')\n",
    "sns.heatmap(acts, cmap='coolwarm', vmin=-1, vmax=1, ax=axes[0])\n",
    "axes[1].set_title('norm_acts')\n",
    "sns.heatmap(norm_acts, cmap='coolwarm', vmin=-1, vmax=1, ax=axes[1])\n",
    "axes[2].set_title('pvals')\n",
    "sns.heatmap(pvals, cmap='viridis_r', ax=axes[2], vmax=1)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c476bc3a",
   "metadata": {},
   "source": [
    "We can observe that for transcription factors T1 and T3, the obtained activities correctly distinguish the two sample populations. T2, on the other hand, should be down for the second population of samples since it is a repressor. This mislabeling of activities happens because `gsea` cannot model weights when inferring biological activities.\n",
    "\n",
    "When weights are available in the prior knowledge, we definitely recommend using any of the methods that take them into account to get better estimates, one example is the Univariate Linear Model method `ulm`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "20525e79",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>T1</th>\n",
       "      <th>T2</th>\n",
       "      <th>T3</th>\n",
       "      <th>T4</th>\n",
       "      <th>T5</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>S01</th>\n",
       "      <td>4.020364</td>\n",
       "      <td>1.667426</td>\n",
       "      <td>-1.378734</td>\n",
       "      <td>-0.243605</td>\n",
       "      <td>-1.188728</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>S02</th>\n",
       "      <td>4.060294</td>\n",
       "      <td>1.392356</td>\n",
       "      <td>-1.313069</td>\n",
       "      <td>-0.387175</td>\n",
       "      <td>-1.102454</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>S03</th>\n",
       "      <td>4.189780</td>\n",
       "      <td>1.086979</td>\n",
       "      <td>-1.346471</td>\n",
       "      <td>-0.294281</td>\n",
       "      <td>-1.139018</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>S04</th>\n",
       "      <td>4.149534</td>\n",
       "      <td>1.395950</td>\n",
       "      <td>-1.332407</td>\n",
       "      <td>-0.273508</td>\n",
       "      <td>-1.197696</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>S05</th>\n",
       "      <td>4.052074</td>\n",
       "      <td>1.610522</td>\n",
       "      <td>-1.534533</td>\n",
       "      <td>-0.311155</td>\n",
       "      <td>-0.990895</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           T1        T2        T3        T4        T5\n",
       "S01  4.020364  1.667426 -1.378734 -0.243605 -1.188728\n",
       "S02  4.060294  1.392356 -1.313069 -0.387175 -1.102454\n",
       "S03  4.189780  1.086979 -1.346471 -0.294281 -1.139018\n",
       "S04  4.149534  1.395950 -1.332407 -0.273508 -1.197696\n",
       "S05  4.052074  1.610522 -1.534533 -0.311155 -0.990895"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# For this toy data, we need to set min_n to 0 (otherwise it is better to keep at 5):\n",
    "acts, pvals = dc.run_ulm(mat, net, min_n=0)\n",
    "acts.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ecc8fe7",
   "metadata": {},
   "source": [
    "In this case, `ulm` only returns infered activities and their associated p-value.\n",
    "\n",
    "As before, let us plot the resulting activities:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "9c61d04b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x216 with 4 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axes = plt.subplots(1,2, figsize=(6,3), tight_layout=True, sharey=True)\n",
    "\n",
    "axes[0].set_title('acts')\n",
    "sns.heatmap(acts, cmap='coolwarm', vmin=-1, vmax=1, ax=axes[0])\n",
    "axes[1].set_title('pvals')\n",
    "sns.heatmap(pvals, cmap='viridis_r', ax=axes[1], vmax=1)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c21c032",
   "metadata": {},
   "source": [
    "Since `ulm` models weights when estimating biological activities, it correctly assigns T2 as inactive in the second population of samples."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7e00a68b",
   "metadata": {},
   "source": [
    "### Multiple methods\n",
    "\n",
    "`decoupler` also allows to run multiple methods at the same time. Moreover, it computes a consensus score based on the obtained activities across methods, called `consensus`.\n",
    "\n",
    "By default, `decouple` runs only the top performer methods in our benchmark (`mlm`, `ulm` and `wsum`), and estimates a consensus score across them. Specific arguments to specific methods can be passed using the variable `args`. For more information check `?decouple`. If we wanted to only obtain the consensus score, we could also have used `run_consensus`, check `?run_consensus` for more information."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "e3825926",
   "metadata": {},
   "outputs": [],
   "source": [
    "# For this toy data, we need to set min_n to 0 (otherwise it is better to keep at 5):\n",
    "results = dc.decouple(mat, net, min_n=0, verbose=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0fb3db1b",
   "metadata": {},
   "source": [
    "`decouple` either returns a dictionary of activities and p-values, or stores them in the `AnnData` instance provided. \n",
    "\n",
    "Let us see how the consensus score looks like:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "ddedb9dd",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Extract from dictionary\n",
    "acts = results['consensus_estimate']\n",
    "pvals = results['consensus_pvals']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "ca700b0f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x216 with 4 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axes = plt.subplots(1,2, figsize=(6,3), tight_layout=True, sharey=True)\n",
    "\n",
    "axes[0].set_title('acts')\n",
    "sns.heatmap(acts, cmap='coolwarm', vmin=-1, vmax=1, ax=axes[0])\n",
    "axes[1].set_title('pvals')\n",
    "sns.heatmap(pvals, cmap='viridis_r', ax=axes[1], vmax=1)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "65e14da3",
   "metadata": {},
   "source": [
    "We can observe that the consensus score correctly predicts that T1 and T2 should be active in the first population of samples while T3 and T4 in the second one. T5 is inactive everywhere as expected."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "decoupler",
   "language": "python",
   "name": "decoupler"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
